package com.qlslylq.ad.sdk.core.mgr;

import com.qlslylq.ad.sdk.application.AdMergeSDKApp;
import com.qlslylq.ad.sdk.constant.AppConst;
import com.qlslylq.ad.sdk.core.ad.BaseAd;
import com.qlslylq.ad.sdk.core.factory.AdFactory;
import com.qlslylq.ad.sdk.enums.AdType;
import com.qlslylq.ad.sdk.model.rsp.AdPlaceWebConfigureVO;
import com.qlslylq.ad.sdk.util.Log;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * created by qlslylq <br/>
 * on 2022/2/11 <br/>
 * 广告池管理类<br/>
 */
public class PoolMgr<T extends BaseAd> {

    private static PoolMgr instance;

    private PoolMgr() {

    }

    public static PoolMgr getInstance() {
        if (instance == null) {
            instance = new PoolMgr();
        }
        return instance;
    }

    /**
     * 获取当前广告池<br/>
     */
    public List<List<T>> getPool(AdType adType) {
        switch (adType) {
            case SPLASH:
                return AdMergeSDKApp.get().getSplashPool();
            case INTERSTITIAL:
                return AdMergeSDKApp.get().getInterstitialPool();
            case REWARDED:
                return AdMergeSDKApp.get().getRewardPool();
            case FULLSCREEN:
                return AdMergeSDKApp.get().getFullScreenPool();
            case BANNER:
                return AdMergeSDKApp.get().getBannerPool();
            case FEED:
                return AdMergeSDKApp.get().getFeedPool();
        }
        return null;
    }

    /**
     * 设置当前广告池<br/>
     */
    private void setPool(AdType adType, List<List<T>> pool) {
        Log.dp("refreshPool");
        switch (adType) {
            case SPLASH:
                AdMergeSDKApp.get().setSplashPool(pool);
                break;
            case INTERSTITIAL:
                AdMergeSDKApp.get().setInterstitialPool(pool);
                break;
            case REWARDED:
                AdMergeSDKApp.get().setRewardPool(pool);
                break;
            case FULLSCREEN:
                AdMergeSDKApp.get().setFullScreenPool(pool);
                break;
            case BANNER:
                AdMergeSDKApp.get().setBannerPool(pool);
                break;
            case FEED:
                AdMergeSDKApp.get().setFeedPool(pool);
                break;
        }
        output(adType);
    }

    /**
     * 重置广告池<br/>
     */
    public void resetAllPool() {
        for (AdType adType : AdType.values()) {
            setPool(adType, null);
        }
    }

    /**
     * 入列<br/>
     * 无法识别的广告类型或广告源为null时禁止入列<br/>
     * 入列时禁止检查广告过期问题<br/>
     */
    public void push(Object adThird, AdPlaceWebConfigureVO config) {
        Log.dp("push");
        T ad = AdFactory.createAd(adThird, config);
        if (ad == null) {
            return;
        }

        List<List<T>> pool = getPool(config.getAdType());
        int groupIndex = config.getGroupIndex();
        while (pool.size() < groupIndex + 1) {
            List<T> list = new ArrayList<>();
            pool.add(list);
        }
        pool.get(groupIndex).add(ad);
        setPool(config.getAdType(), pool);
    }

    /**
     * 入列<br/>
     * 无法识别的广告类型或广告源为null时禁止入列<br/>
     * 入列时禁止检查广告过期问题<br/>
     */
    public void pushSome(List<?> adThirds, AdPlaceWebConfigureVO config) {
        Log.dp("push");
        List<T> ads = AdFactory.createAds(adThirds, config);
        if (ads == null || ads.isEmpty()) {
            return;
        }

        List<List<T>> pool = getPool(config.getAdType());
        int groupIndex = config.getGroupIndex();
        while (pool.size() < groupIndex + 1) {
            List<T> list = new ArrayList<>();
            pool.add(list);
        }
        pool.get(groupIndex).addAll(ads);
        setPool(config.getAdType(), pool);
    }

    /**
     * 出列<br/>
     * 内组size为0时，禁止删除内组，否则会导致groupIndex前移致下次pop错误及push跳组<br/>
     */
    public void pop(T ad) {
        Log.dp("pop");
        List<List<T>> pool = getPool(ad.getConfig().getAdType());
        int groupIndex = ad.getConfig().getGroupIndex();
        pool.get(groupIndex).remove(ad);
        setPool(ad.getConfig().getAdType(), pool);
    }

    /**
     * 外抛<br/>
     */
    public T first(AdType adType) {
        List<List<T>> pool = getPool(adType);
        List<T> list = null;
        for (List<T> item : pool) {
            if (item.size() > 0) {
                list = item;
                break;
            }
        }
        T ad = list.stream().max(Comparator.comparing(T::getWeight)).get();
        return ad;
    }

    /**
     * 获取广告池的动态容量<br/>
     */
    public int size(AdType adType) {
        int totalCount = 0;
        List<List<T>> pool = getPool(adType);
        for (List<T> list : pool) {
            totalCount += list.size();
        }
        return totalCount;
    }

    /**
     * 广告池的动态容量是否已清零<br/>
     */
    public boolean isEmpty(AdType adType) {
        List<List<T>> pool = getPool(adType);
        for (List<T> list : pool) {
            if (list.size() > 0) {
                return false;
            }
        }
        return true;
    }

    /**
     * 打印当前广告池<br/>
     */
    public void output(AdType adType) {
        if (AppConst.openSecretLog) {
            List<List<T>> pool = getPool(adType);
            Log.dp(String.format("当前广告缓存池[%s]：", adType.getId()) + pool);
        }
    }
}
